

<!DOCTYPE html>
<html>
  <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# githubog: http://ogp.me/ns/fb/githubog#">
    <meta charset='utf-8'>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>第七章  增加标签和标签页面 · nswbmw/N-blog Wiki · GitHub</title>
    <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub" />
    <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub" />
    <link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-114.png" />
    <link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114.png" />
    <link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-144.png" />
    <link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144.png" />
    <link rel="logo" type="image/svg" href="https://github-media-downloads.s3.amazonaws.com/github-logo.svg" />
    <meta property="og:image" content="https://a248.e.akamai.net/assets.github.com/images/modules/logos_page/Octocat.png">
    <link rel="assets" href="https://a248.e.akamai.net/assets.github.com/">
    <link rel="xhr-socket" href="/_sockets" />
    
    


    <meta name="msapplication-TileImage" content="/windows-tile.png" />
    <meta name="msapplication-TileColor" content="#ffffff" />
    <meta name="selected-link" value="repo_wiki" data-pjax-transient />
    <meta content="collector.githubapp.com" name="octolytics-host" /><meta content="github" name="octolytics-app-id" />

    
    
    <link rel="icon" type="image/x-icon" href="/favicon.ico" />

    <meta content="authenticity_token" name="csrf-param" />
<meta content="mMbbniz0wLvdAfQLN+Kz/Pcr+UepJxX56bVg9rBIy+Q=" name="csrf-token" />

    <link href="https://a248.e.akamai.net/assets.github.com/assets/github-be6069435cb0250bd316958375c0de713801bdf5.css" media="all" rel="stylesheet" type="text/css" />
    <link href="https://a248.e.akamai.net/assets.github.com/assets/github2-91a602bfb8b2a53f90aa7aea127a69e4f9ef1f11.css" media="all" rel="stylesheet" type="text/css" />
    


      <script src="https://a248.e.akamai.net/assets.github.com/assets/frameworks-1f72571b966545f4e27481a3b0ebbeeed4f2f139.js" type="text/javascript"></script>
      <script src="https://a248.e.akamai.net/assets.github.com/assets/github-3b51dd74a94c713c22309e373955e5fa02a3bb65.js" type="text/javascript"></script>
      
      <meta http-equiv="x-pjax-version" content="f5ee7511175547406ed413cec6ae4c9b">

        <script src="https://a248.e.akamai.net/assets.github.com/assets/wiki-5f94f237a61cfac742b656f8a10702b3b86e9b37.js" type="text/javascript"></script>

  <meta property="og:title" content="N-blog"/>
  <meta property="og:type" content="githubog:gitrepository"/>
  <meta property="og:url" content="https://github.com/nswbmw/N-blog"/>
  <meta property="og:image" content="https://a248.e.akamai.net/assets.github.com/images/gravatars/gravatar-user-420.png"/>
  <meta property="og:site_name" content="GitHub"/>
  <meta property="og:description" content="N-blog - 使用 Express + MongoDB 搭建多人博客"/>

  <meta name="description" content="N-blog - 使用 Express + MongoDB 搭建多人博客" />

  <meta content="4279697" name="octolytics-dimension-user_id" /><meta content="nswbmw" name="octolytics-dimension-user_login" /><meta content="10309334" name="octolytics-dimension-repository_id" /><meta content="nswbmw/N-blog" name="octolytics-dimension-repository_nwo" /><meta content="true" name="octolytics-dimension-repository_public" /><meta content="false" name="octolytics-dimension-repository_is_fork" /><meta content="10309334" name="octolytics-dimension-repository_network_root_id" /><meta content="nswbmw/N-blog" name="octolytics-dimension-repository_network_root_nwo" />
  <link href="https://github.com/nswbmw/N-blog/commits/master.atom" rel="alternate" title="Recent Commits to N-blog:master" type="application/atom+xml" />

  </head>


  <body class="logged_out  windows vis-public env-production  kill-the-chrome">

    <div class="wrapper">
      
      
      

      
      <div class="header header-logged-out">
  <div class="container clearfix">

    <a class="header-logo-wordmark" href="https://github.com/">
      <span class="mega-octicon octicon-logo-github"></span>
    </a>

    <div class="header-actions">
      <a class="button primary" href="/signup">Sign up</a>
      <a class="button" href="/login?return_to=%2Fnswbmw%2FN-blog%2Fwiki%2F%25E7%25AC%25AC%25E4%25B8%2583%25E7%25AB%25A0--%25E5%25A2%259E%25E5%258A%25A0%25E6%25A0%2587%25E7%25AD%25BE%25E5%2592%258C%25E6%25A0%2587%25E7%25AD%25BE%25E9%25A1%25B5%25E9%259D%25A2">Sign in</a>
    </div>

    <div class="command-bar js-command-bar  in-repository">


      <ul class="top-nav">
          <li class="explore"><a href="/explore">Explore</a></li>
        <li class="features"><a href="/features">Features</a></li>
          <li class="enterprise"><a href="https://enterprise.github.com/">Enterprise</a></li>
          <li class="blog"><a href="/blog">Blog</a></li>
      </ul>
        <form accept-charset="UTF-8" action="/search" class="command-bar-form" id="top_search_form" method="get">

<input type="text" data-hotkey="/ s" name="q" id="js-command-bar-field" placeholder="Search or type a command" tabindex="1" autocapitalize="off"
    
    
      data-repo="nswbmw/N-blog"
      data-branch="master"
      data-sha="b92eb6240e468e36eb30948e5c92920e83ddc7fa"
  >

    <input type="hidden" name="nwo" value="nswbmw/N-blog" />

    <div class="select-menu js-menu-container js-select-menu search-context-select-menu">
      <span class="minibutton select-menu-button js-menu-target">
        <span class="js-select-button">This repository</span>
      </span>

      <div class="select-menu-modal-holder js-menu-content js-navigation-container">
        <div class="select-menu-modal">

          <div class="select-menu-item js-navigation-item selected">
            <span class="select-menu-item-icon octicon octicon-check"></span>
            <input type="radio" class="js-search-this-repository" name="search_target" value="repository" checked="checked" />
            <div class="select-menu-item-text js-select-button-text">This repository</div>
          </div> <!-- /.select-menu-item -->

          <div class="select-menu-item js-navigation-item">
            <span class="select-menu-item-icon octicon octicon-check"></span>
            <input type="radio" name="search_target" value="global" />
            <div class="select-menu-item-text js-select-button-text">All repositories</div>
          </div> <!-- /.select-menu-item -->

        </div>
      </div>
    </div>

  <span class="octicon help tooltipped downwards" title="Show command bar help">
    <span class="octicon octicon-question"></span>
  </span>


  <input type="hidden" name="ref" value="cmdform">

</form>
    </div>

  </div>
</div>


      


          <div class="site" itemscope itemtype="http://schema.org/WebPage">
    
    <div class="pagehead repohead instapaper_ignore readability-menu">
      <div class="container">
        

<ul class="pagehead-actions">



    <li>
      <a href="/login?return_to=%2Fnswbmw%2FN-blog"
        class="minibutton with-count js-toggler-target star-button entice tooltipped upwards"
        title="You must be signed in to use this feature" rel="nofollow">
        <span class="octicon octicon-star"></span>Star
      </a>
      <a class="social-count js-social-count" href="/nswbmw/N-blog/stargazers">
        120
      </a>
    </li>
    <li>
      <a href="/login?return_to=%2Fnswbmw%2FN-blog"
        class="minibutton with-count js-toggler-target fork-button entice tooltipped upwards"
        title="You must be signed in to fork a repository" rel="nofollow">
        <span class="octicon octicon-git-branch"></span>Fork
      </a>
      <a href="/nswbmw/N-blog/network" class="social-count">
        76
      </a>
    </li>
</ul>

        <h1 itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="entry-title public">
          <span class="repo-label"><span>public</span></span>
          <span class="mega-octicon octicon-repo"></span>
          <span class="author">
            <a href="/nswbmw" class="url fn" itemprop="url" rel="author"><span itemprop="title">nswbmw</span></a></span
          ><span class="repohead-name-divider">/</span><strong
          ><a href="/nswbmw/N-blog" class="js-current-repository js-repo-home-link">N-blog</a></strong>

          <span class="page-context-loader">
            <img alt="Octocat-spinner-32" height="16" src="https://a248.e.akamai.net/assets.github.com/images/spinners/octocat-spinner-32.gif" width="16" />
          </span>

        </h1>
      </div><!-- /.container -->
    </div><!-- /.repohead -->

    <div class="container">

      <div class="repository-with-sidebar repo-container
            ">

          <div class="repository-sidebar">

              

<div class="repo-nav repo-nav-full js-repository-container-pjax js-octicon-loaders">
  <div class="repo-nav-contents">
    <ul class="repo-menu">
      <li class="tooltipped leftwards" title="Code">
        <a href="/nswbmw/N-blog" class="js-selected-navigation-item " data-gotokey="c" data-pjax="true" data-selected-links="repo_source repo_downloads repo_commits repo_tags repo_branches /nswbmw/N-blog">
          <span class="octicon octicon-code"></span> <span class="full-word">Code</span>
          <img alt="Octocat-spinner-32" class="mini-loader" height="16" src="https://a248.e.akamai.net/assets.github.com/images/spinners/octocat-spinner-32.gif" width="16" />
</a>      </li>

        <li class="tooltipped leftwards" title="Issues">
          <a href="/nswbmw/N-blog/issues" class="js-selected-navigation-item js-disable-pjax" data-gotokey="i" data-selected-links="repo_issues /nswbmw/N-blog/issues">
            <span class="octicon octicon-issue-opened"></span> <span class="full-word">Issues</span>
            <span class='counter'>1</span>
            <img alt="Octocat-spinner-32" class="mini-loader" height="16" src="https://a248.e.akamai.net/assets.github.com/images/spinners/octocat-spinner-32.gif" width="16" />
</a>        </li>

      <li class="tooltipped leftwards" title="Pull Requests"><a href="/nswbmw/N-blog/pulls" class="js-selected-navigation-item js-disable-pjax" data-gotokey="p" data-selected-links="repo_pulls /nswbmw/N-blog/pulls">
            <span class="octicon octicon-git-pull-request"></span> <span class="full-word">Pull Requests</span>
            <span class='counter'>0</span>
            <img alt="Octocat-spinner-32" class="mini-loader" height="16" src="https://a248.e.akamai.net/assets.github.com/images/spinners/octocat-spinner-32.gif" width="16" />
</a>      </li>


        <li class="tooltipped leftwards" title="Wiki">
          <a href="/nswbmw/N-blog/wiki" class="js-selected-navigation-item selected" data-pjax="true" data-selected-links="repo_wiki /nswbmw/N-blog/wiki">
            <span class="octicon octicon-book"></span> <span class="full-word">Wiki</span>
            <img alt="Octocat-spinner-32" class="mini-loader" height="16" src="https://a248.e.akamai.net/assets.github.com/images/spinners/octocat-spinner-32.gif" width="16" />
</a>        </li>


    </ul>
    <div class="repo-menu-separator"></div>
    <ul class="repo-menu">

      <li class="tooltipped leftwards" title="Pulse">
        <a href="/nswbmw/N-blog/pulse" class="js-selected-navigation-item " data-pjax="true" data-selected-links="pulse /nswbmw/N-blog/pulse">
          <span class="octicon octicon-pulse"></span> <span class="full-word">Pulse</span>
          <img alt="Octocat-spinner-32" class="mini-loader" height="16" src="https://a248.e.akamai.net/assets.github.com/images/spinners/octocat-spinner-32.gif" width="16" />
</a>      </li>

      <li class="tooltipped leftwards" title="Graphs">
        <a href="/nswbmw/N-blog/graphs" class="js-selected-navigation-item " data-pjax="true" data-selected-links="repo_graphs repo_contributors /nswbmw/N-blog/graphs">
          <span class="octicon octicon-graph"></span> <span class="full-word">Graphs</span>
          <img alt="Octocat-spinner-32" class="mini-loader" height="16" src="https://a248.e.akamai.net/assets.github.com/images/spinners/octocat-spinner-32.gif" width="16" />
</a>      </li>

      <li class="tooltipped leftwards" title="Network">
        <a href="/nswbmw/N-blog/network" class="js-selected-navigation-item js-disable-pjax" data-selected-links="repo_network /nswbmw/N-blog/network">
          <span class="octicon octicon-git-branch"></span> <span class="full-word">Network</span>
          <img alt="Octocat-spinner-32" class="mini-loader" height="16" src="https://a248.e.akamai.net/assets.github.com/images/spinners/octocat-spinner-32.gif" width="16" />
</a>      </li>

    </ul>

  </div>
</div>


              <div class="only-with-full-nav">

                

  

<div class="clone-url open"
  data-protocol-type="http"
  data-url="/users/set_protocol?protocol_selector=http&amp;protocol_type=clone">
  <h3><strong>HTTPS</strong> clone URL</h3>

  <input type="text" class="clone js-url-field"
         value="https://github.com/nswbmw/N-blog.git" readonly="readonly">

  <span class="js-zeroclipboard url-box-clippy minibutton zeroclipboard-button" data-clipboard-text="https://github.com/nswbmw/N-blog.git" data-copied-hint="copied!" title="copy to clipboard"><span class="octicon octicon-clippy"></span></span>
</div>

  

<div class="clone-url "
  data-protocol-type="subversion"
  data-url="/users/set_protocol?protocol_selector=subversion&amp;protocol_type=clone">
  <h3><strong>Subversion</strong> checkout URL</h3>

  <input type="text" class="clone js-url-field"
         value="https://github.com/nswbmw/N-blog" readonly="readonly">

  <span class="js-zeroclipboard url-box-clippy minibutton zeroclipboard-button" data-clipboard-text="https://github.com/nswbmw/N-blog" data-copied-hint="copied!" title="copy to clipboard"><span class="octicon octicon-clippy"></span></span>
</div>



<p class="clone-options">You can clone with
    <a href="#" class="js-clone-selector" data-protocol="http">HTTPS</a>,
    <a href="#" class="js-clone-selector" data-protocol="subversion">Subversion</a>,
  and <a href="https://help.github.com/articles/which-remote-url-should-i-use">other methods.</a>
</p>


  <a href="http://windows.github.com" class="minibutton sidebar-button">
    <span class="octicon octicon-device-desktop"></span>
    Clone in Desktop
  </a>


                  <a href="/nswbmw/N-blog/archive/master.zip"
                     class="minibutton sidebar-button"
                     title="Download this repository as a zip file"
                     rel="nofollow">
                    <span class="octicon octicon-cloud-download"></span>
                    Download ZIP
                  </a>

              </div>
          </div>

          <div id="js-repo-pjax-container" class="repository-content context-loader-container" data-pjax-container>
            

<div class="tabnav">
  <ul class="tabnav-tabs">
    <li><a href="/nswbmw/N-blog/wiki" class="js-selected-navigation-item tabnav-tab" data-selected-links=" /nswbmw/N-blog/wiki">Home</a></li>
    <li><a href="/nswbmw/N-blog/wiki/_pages" class="js-selected-navigation-item tabnav-tab" data-selected-links=" /nswbmw/N-blog/wiki/_pages">Pages</a></li>
    <li><a href="/nswbmw/N-blog/wiki/_history" class="js-selected-navigation-item tabnav-tab" data-selected-links=" /nswbmw/N-blog/wiki/_history">History</a></li>
  </ul>
  <div class="tabnav-right">
    <div class="tabnav-widget">
      <a href="/nswbmw/N-blog/wiki/_new" class="button minibutton primary js-new-wiki-page">New Page</a>
    </div>
  </div>
</div>



<div id="wiki-wrapper" class="page">
<div id="head">
  <ul class="wiki-actions readability-extra">
    <li class="gollum-minibutton"><a href="/nswbmw/N-blog/wiki/%E7%AC%AC%E4%B8%83%E7%AB%A0--%E5%A2%9E%E5%8A%A0%E6%A0%87%E7%AD%BE%E5%92%8C%E6%A0%87%E7%AD%BE%E9%A1%B5%E9%9D%A2/_history"
       class="minibutton bigger action-page-history">
       Page History
     </a></li>
    <li class="gollum-minibutton"><span class="js-zeroclipboard minibutton" data-clipboard-text="https://github.com/nswbmw/N-blog.wiki.git" data-copied-hint="copied!" title="Click to copy url to clipboard">Clone URL</span></li>
  </ul>
  <h1 class="instapaper_title">第七章  增加标签和标签页面</h1>
</div>
<div id="wiki-content">
  <div class="wrap">
  <div id="wiki-body" class="gollum-markdown-content instapaper_body">
    <div class="markdown-body">
      <p>现在我们来给博客增加标签和标签页。我们设定每篇文章最多有三个标签（少于三个也可以），当点击主页左侧标签页（tag）链接时，跳转到标签页并列出所有已存在标签；当点击任意一个标签链接时，跳转到该标签页并列出所有含有该标签的文章。</p>

<h3>
<a name="" class="anchor" href="#"><span class="octicon octicon-link"></span></a>添加标签</h3>

<p>首先我们来实现添加标签功能。<br>
修改 post.ejs ，在 <code>&lt;input type="text" name="title" /&gt;&lt;br /&gt;</code> 后添加：</p>

<pre><code>标签：&lt;br /&gt;
&lt;input type="text" name="tag1" /&gt;&lt;input type="text" name="tag2" /&gt;&lt;input type="text" name="tag3" /&gt;&lt;br /&gt;
</code></pre>

<p>打开 index.js ，修改 <code>app.post('/post')</code> 将</p>

<pre><code>var currentUser = req.session.user,
    post = new Post(currentUser.name, req.body.title, req.body.post);
</code></pre>

<p>修改为：</p>

<pre><code>var currentUser = req.session.user,
    tags = [{"tag":req.body.tag1},{"tag":req.body.tag2},{"tag":req.body.tag3}],
    post = new Post(currentUser.name, req.body.title, tags, req.body.post);
</code></pre>

<p>修改 post.js ，将</p>

<pre><code>function Post(name, title, post) {
  this.name = name;
  this.title= title;
  this.post = post;
}
</code></pre>

<p>修改为：</p>

<pre><code>function Post(name, title, tags, post) {
  this.name = name;
  this.title = title;
  this.tags = tags;
  this.post = post;
}
</code></pre>

<p>将</p>

<pre><code>var post = {
    name: this.name,
    time: time,
    title: this.title,
    post: this.post,
    comments: []
};
</code></pre>

<p>修改为：</p>

<pre><code>var post = {
    name: this.name,
    time: time,
    title: this.title,
    tags: this.tags,
    post: this.post,
    comments: []
};
</code></pre>

<p>现在我们就可以在发表文章的时候添加标签了，接下来我们修改 index.ejs 、 user.ejs 和 article.ejs 来显示文章的标签。</p>

<p>修改 index.ejs 和 user.ejs ，将</p>

<pre><code>&lt;p class="info"&gt;
  作者：&lt;a href="/u/&lt;%= post.name %&gt;"&gt;&lt;%= post.name %&gt;&lt;/a&gt; | 
  日期：&lt;%= post.time.minute %&gt;
&lt;/p&gt;
</code></pre>

<p>修改为：</p>

<pre><code>&lt;p class="info"&gt;
  作者：&lt;a href="/u/&lt;%= post.name %&gt;"&gt;&lt;%= post.name %&gt;&lt;/a&gt; | 
  日期：&lt;%= post.time.minute %&gt; | 
  标签：
  &lt;% post.tags.forEach(function(tag, index){ %&gt;
    &lt;% if(tag.tag){ %&gt;
      &lt;a class="tag" href="/tags/&lt;%= tag.tag %&gt;"&gt;&lt;%= tag.tag %&gt;&lt;/a&gt;
    &lt;% } %&gt;
  &lt;% }) %&gt;
&lt;/p&gt;
</code></pre>

<p>修改 article.ejs ，将</p>

<pre><code>&lt;p class="info"&gt;
  作者：&lt;a href="/u/&lt;%= post.name %&gt;"&gt;&lt;%= post.name %&gt;&lt;/a&gt; | 
  日期：&lt;%= post.time.minute %&gt;
&lt;/p&gt;
</code></pre>

<p>修改为：</p>

<pre><code>&lt;p class="info"&gt;
  作者：&lt;a href="/u/&lt;%= post.name %&gt;"&gt;&lt;%= post.name %&gt;&lt;/a&gt; | 
  日期：&lt;%= post.time.minute %&gt; | 
  标签：
  &lt;% post.tags.forEach(function(tag, index){ %&gt;
    &lt;% if(tag.tag){ %&gt;
      &lt;a class="tag" href="/tags/&lt;%= tag.tag %&gt;"&gt;&lt;%= tag.tag %&gt;&lt;/a&gt;
    &lt;% } %&gt;
  &lt;% }) %&gt;
&lt;/p&gt;
</code></pre>

<p>最后，在 header.ejs 中添加如下样式：</p>

<pre><code>.tag{background-color:#ff0000;border-radius:3px;font-size:14px;color:#ffffff;display:inline-block;padding:0 5px;margin-bottom:8px;}
.tag:hover{text-decoration:none;background-color:#ffffff;color:#000000;-webkit-transition:color .2s linear;}
</code></pre>

<p>至此，我们给博客添加了标签功能。</p>

<h3>
<a name="-1" class="anchor" href="#-1"><span class="octicon octicon-link"></span></a>添加标签页</h3>

<p>接下来我们增加标签页。<br>
修改 header.ejs ，在 <code>&lt;span&gt;&lt;a title="存档" href="/archive"&gt;archive&lt;/a&gt;&lt;/span&gt;</code> 下一行添加：</p>

<pre><code>&lt;span&gt;&lt;a title="标签" href="/tags"&gt;tags&lt;/a&gt;&lt;/span&gt;
</code></pre>

<p>修改 index.js ，在 <code>app.get('/archive')</code> 后添加如下代码：</p>

<pre><code>app.get('/tags', function(req,res){
  Post.getTags(function(err, posts){
    if(err){
      req.flash('error',err); 
      return res.redirect('/');
    }
    res.render('tags',{
      title: '标签',
      posts: posts,
      user: req.session.user,
      success: req.flash('success').toString(),
      error: req.flash('error').toString()
    });
  });
});
</code></pre>

<p>打开 post.js ，在最后添加：</p>

<pre><code>Post.getTags = function(callback) {//返回所有标签
  mongodb.open(function (err, db) {
    if (err) {
      return callback(err);
    }
    db.collection('posts', function(err, collection) {
      if (err) {
        mongodb.close();
        return callback(err);
      }
      //distinct 用来找出给定键的所有不同值
      collection.distinct("tags.tag",function(err, docs){
        mongodb.close();
        if (err) {
          callback(err, null);
        }
        callback(null, docs);
      });
    });
  });
};
</code></pre>

<p><strong>注意</strong>：这里我们用了 distinct （详见《mongodb权威指南》）找出 tag 键的所有不同值，因为有时候我们发表文章的标签是一样的，所以这样避免了获取重复的标签。</p>

<p>在 views 文件夹下新建 tags.ejs ，添加如下代码：</p>

<pre><code>&lt;%- include header %&gt;
&lt;% posts.forEach(function(tag, index){ %&gt;
  &lt;% if(tag){ %&gt;
    &lt;a class="tag" href="/tags/&lt;%= tag %&gt;"&gt;&lt;%= tag %&gt;&lt;/a&gt;
  &lt;% } %&gt;
&lt;% }) %&gt;
&lt;%- include footer %&gt;
</code></pre>

<p>至此，我们就给博客添加了标签页。</p>

<h3>
<a name="-2" class="anchor" href="#-2"><span class="octicon octicon-link"></span></a>添加特定标签的页面</h3>

<p>现在我们添加特定标签的页面，即当点击任意一个标签链接时，跳转到该标签页并列出所有含有该标签的文章。<br>
修改 post.js ，在最后添加如下代码：</p>

<pre><code>Post.getTag = function(tag, callback) {//返回含有特定标签的所有文章
  mongodb.open(function (err, db) {
    if (err) {
      return callback(err);
    }
    db.collection('posts', function(err, collection) {
      if (err) {
        mongodb.close();
        return callback(err);
      }
      //通过 tags.tag 查询并返回只含有 name、time、title 键的文档组成的数组
      collection.find({"tags.tag":tag},{"name":1,"time":1,"title":1}).sort({
        time:-1
      }).toArray(function(err, docs){
        mongodb.close();
        if (err) {
          callback(err, null);
        }
        callback(null, docs);
      });
    });
  });
};
</code></pre>

<p>修改 index.js ，在 <code>app.get('/tags')</code> 后添加如下代码：</p>

<pre><code>app.get('/tags/:tag', function(req,res){
  Post.getTag(req.params.tag, function(err, posts){
    if(err){
      req.flash('error',err); 
      return res.redirect('/');
    }
    res.render('tag',{
      title: 'TAG:'+req.params.tag,
      posts: posts,
      user: req.session.user,
      success: req.flash('success').toString(),
      error: req.flash('error').toString()
    });
  });
});
</code></pre>

<p>在 views 文件夹下新建 tag.ejs ，添加如下代码：</p>

<pre><code>&lt;%- include header %&gt;
&lt;ul class="archive"&gt;
&lt;% var lastYear=0 %&gt;
&lt;% posts.forEach(function(post, index){ %&gt;
  &lt;% if(lastYear!=post.time.year){ %&gt;
    &lt;li&gt;&lt;h3&gt;&lt;%= post.time.year %&gt;&lt;/h3&gt;&lt;/li&gt;
  &lt;% lastYear=post.time.year } %&gt;
    &lt;li&gt;&lt;time&gt;&lt;%= post.time.day %&gt;&lt;/time&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="/u/&lt;%= post.name %&gt;/&lt;%= post.time.day %&gt;/&lt;%= post.title %&gt;"&gt;&lt;%= post.title %&gt;&lt;/a&gt;&lt;/li&gt;
&lt;% }) %&gt;
&lt;/ul&gt;
&lt;%- include footer %&gt;
</code></pre>

<p>现在，我们的博客就增加了标签和标签页的功能。</p>
    </div>
  </div>
  </div>

</div>
<div id="gollum-footer">
  <p id="last-edit">
    Last edited by nswbmw, <time class="js-relative-date" datetime="2013-05-27T02:55:30-07:00" title="2013-05-27 02:55:30">May 27, 2013</time>
  </p>
</div>
</div>


          </div>
        </div>

      </div><!-- /.repo-container -->
      <div class="modal-backdrop"></div>
    </div>
  </div><!-- /.site -->


    </div><!-- /.wrapper -->

      <div class="container">
  <div class="site-footer">
    <ul class="site-footer-links right">
      <li><a href="https://status.github.com/">Status</a></li>
      <li><a href="http://developer.github.com">Developer</a></li>
      <li><a href="http://training.github.com">Training</a></li>
      <li><a href="http://shop.github.com">Shop</a></li>
      <li><a href="/blog">Blog</a></li>
      <li><a href="/about">About</a></li>
    </ul>

    <a href="/">
      <span class="mega-octicon octicon-mark-github"></span>
    </a>

    <ul class="site-footer-links">
      <li>&copy; 2013 <span title="0.09414s from fe3.rs.github.com">GitHub</span>, Inc.</li>
        <li><a href="/site/terms">Terms</a></li>
        <li><a href="/site/privacy">Privacy</a></li>
        <li><a href="/security">Security</a></li>
        <li><a href="/contact">Contact</a></li>
    </ul>
  </div><!-- /.site-footer -->
</div><!-- /.container -->


    <div class="fullscreen-overlay js-fullscreen-overlay" id="fullscreen_overlay">
  <div class="fullscreen-container js-fullscreen-container">
    <div class="textarea-wrap">
      <textarea name="fullscreen-contents" id="fullscreen-contents" class="js-fullscreen-contents" placeholder="" data-suggester="fullscreen_suggester"></textarea>
          <div class="suggester-container">
              <div class="suggester fullscreen-suggester js-navigation-container" id="fullscreen_suggester"
                 data-url="/nswbmw/N-blog/suggestions/commit">
              </div>
          </div>
    </div>
  </div>
  <div class="fullscreen-sidebar">
    <a href="#" class="exit-fullscreen js-exit-fullscreen tooltipped leftwards" title="Exit Zen Mode">
      <span class="mega-octicon octicon-screen-normal"></span>
    </a>
    <a href="#" class="theme-switcher js-theme-switcher tooltipped leftwards"
      title="Switch themes">
      <span class="octicon octicon-color-mode"></span>
    </a>
  </div>
</div>



    <div id="ajax-error-message" class="flash flash-error">
      <span class="octicon octicon-alert"></span>
      <a href="#" class="octicon octicon-remove-close close ajax-error-dismiss"></a>
      Something went wrong with that request. Please try again.
    </div>

    
    <span id='server_response_time' data-time='0.09456' data-host='fe3'></span>
    
  </body>
</html>

